﻿Imports OMANE.Modules.Builder.PredicateExpression

Public Class Vector(Of T As Structure)
    Implements IEnumerable(Of T)

    Private data() As T

    Protected Friend Sub New(ByVal data() As T)
        Me.data = data
    End Sub
    Protected Friend Sub New()

    End Sub
   
    ReadOnly Property Dimension As Integer
        Get
            Return data.Length
        End Get
    End Property

    Default Public Property Item(ByVal index As Integer) As T
        Get
            Return data(index)
        End Get
        Set(ByVal value As T)
            data(index) = value
        End Set
    End Property
    Default Public Property Item(ByVal start As Integer, ByVal [end] As Integer) As Vector(Of T)
        Get
            Dim result As New Vector(Of T)
            ReDim result.data([end] - start)
            Array.Copy(data, start, result.data, 0, [end] - start)
            Return result
        End Get
        Set(ByVal value As Vector(Of T))
            Array.Copy(value.data, 0, data, start, [end] - start)
        End Set
    End Property

    Private Function GetEnumerator() As System.Collections.Generic.IEnumerator(Of T) Implements System.Collections.Generic.IEnumerable(Of T).GetEnumerator
        Return data.GetEnumerator()
    End Function
    Private Function GetEnumerator1() As System.Collections.IEnumerator Implements System.Collections.IEnumerable.GetEnumerator
        Return data.GetEnumerator()

    End Function
End Class

Public Class Predicate(Of T)

    Private _Method As Func(Of T, Boolean)

    Private Sub New(ByVal Method As Func(Of T, Boolean))
        Me._Method = Method
    End Sub

    Public Function Validate(ByVal value As T) As Boolean
        Return _Method(value)
    End Function
    

    Public Shared Widening Operator CType(ByVal value As Boolean) As Predicate(Of T)
        Return New Predicate(Of T)(Function(v As T) value)
    End Operator
    Public Shared Widening Operator CType(ByVal value As Func(Of T, Boolean)) As Predicate(Of T)
        Return New Predicate(Of T)(value)
    End Operator

    Public Shared Operator And(ByVal left As Predicate(Of T), ByVal right As Predicate(Of T)) As Predicate(Of T)
        Return New Predicate(Of T)(Function(v As T) left._Method(v) And right._Method(v))
    End Operator
    Public Shared Operator Or(ByVal left As Predicate(Of T), ByVal right As Predicate(Of T)) As Predicate(Of T)
        Return New Predicate(Of T)(Function(v As T) left._Method(v) Or right._Method(v))
    End Operator
    Public Shared Operator Xor(ByVal left As Predicate(Of T), ByVal right As Predicate(Of T)) As Predicate(Of T)
        Return New Predicate(Of T)(Function(v As T) left._Method(v) Xor right._Method(v))
    End Operator
    Public Shared Operator Not(ByVal left As Predicate(Of T)) As Predicate(Of T)
        Return New Predicate(Of T)(Function(v As T) Not left._Method(v))
    End Operator

    Public Shared Operator =(ByVal left As Predicate(Of T), ByVal right As Predicate(Of T)) As Predicate(Of T)
        Return New Predicate(Of T)(Function(v As T) left._Method(v) = right._Method(v))
    End Operator
    Public Shared Operator <>(ByVal left As Predicate(Of T), ByVal right As Predicate(Of T)) As Predicate(Of T)
        Return New Predicate(Of T)(Function(v As T) left._Method(v) <> right._Method(v))
    End Operator
End Class

Public Class PredicateExpression

    Private _Expression As Expressions.Expression

    Protected Sub New(ByVal Expression As Expressions.Expression)
        Me._Expression = Expression
    End Sub


    Public Function GetExpression() As Expressions.Expression
        'Dim a As PredicateExpression = 2.0
        'a = (a + 1.0) / (a - 1.0)
        'a = [If](a > 0.5, 0.25, 0.75)
        Return _Expression
    End Function
    

    Public Shared Widening Operator CType(ByVal value As Double) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.Constant(value))
    End Operator
    Public Shared Widening Operator CType(ByVal value As Integer) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.Constant(value))
    End Operator
    Public Shared Widening Operator CType(ByVal value As Boolean) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.Constant(value))
    End Operator
    Public Shared Widening Operator CType(ByVal value As String) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.Constant(value))
    End Operator

    Public Shared Operator +(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.AddChecked(left._Expression, right._Expression))
    End Operator
    Public Shared Operator -(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.SubtractChecked(left._Expression, right._Expression))
    End Operator
    Public Shared Operator /(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.Divide(left._Expression, right._Expression))
    End Operator
    Public Shared Operator *(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.MultiplyChecked(left._Expression, right._Expression))
    End Operator

    Public Shared Operator <(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.LessThan(left._Expression, right._Expression))
    End Operator
    Public Shared Operator >(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.GreaterThan(left._Expression, right._Expression))
    End Operator
    Public Shared Operator <=(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.LessThanOrEqual(left._Expression, right._Expression))
    End Operator
    Public Shared Operator >=(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.GreaterThanOrEqual(left._Expression, right._Expression))
    End Operator

    Public Shared Operator And(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.And(left._Expression, right._Expression))
    End Operator
    Public Shared Operator Or(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.Or(left._Expression, right._Expression))
    End Operator
    Public Shared Operator =(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.Equal(left._Expression, right._Expression))
    End Operator
    Public Shared Operator <>(ByVal left As PredicateExpression, ByVal right As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.NotEqual(left._Expression, right._Expression))
    End Operator

    Public Shared Operator -(ByVal left As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.NegateChecked(left._Expression))
    End Operator
    Public Shared Operator Not(ByVal left As PredicateExpression) As PredicateExpression
        Return New PredicateExpression(Expressions.Expression.Not(left._Expression))
    End Operator

    Public Shared Function [If](ByVal test As PredicateExpression, ByVal truetest As PredicateExpression, ByVal falsetest As PredicateExpression) As PredicateExpression

    End Function
    Public Shared Function [Choose](ByVal test As PredicateExpression, ByVal ParamArray truetest() As PredicateExpression) As PredicateExpression

    End Function

End Class

Public Class PredicateExpression(Of T)
    Inherits PredicateExpression

    Private parameter As Expressions.ParameterExpression

    Protected Sub New(ByVal Expression As Expressions.Expression)
        MyBase.New(Expression)
    End Sub

    Public Overloads Function GetFunction() As Expressions.Expression(Of Func(Of T, Boolean))
        Return Expressions.Expression.Lambda(Of Func(Of T, Boolean))( _
            Me.GetExpression(), parameter)
    End Function
End Class

Public Class BoolVector
    Inherits Vector(Of Boolean)
End Class

Public Class DoubleVector
    Inherits Vector(Of Double)

End Class
